package pl.uz.zgora.plan;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.preference.Preference;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;

public class SOAPManager {
	/** Adres serwera SOAP */
	//public static final String HOST_ADDR = "10.0.2.2:80";
	//private static final String SERVICE_URL = "http://porto.iie.uz.zgora.pl/timetable/public/index.php/index/wsdl";
	public static final String MAIN_SERVICE_URL = "http://porto.iie.uz.zgora.pl/timetable/public/index.php/index/wsdl";
	public static String SERVICE_URL = MAIN_SERVICE_URL;
	public static final String SERVICE_NAMESPACE = SERVICE_URL;
	
	private SoapObject soapRequest = null;
	private SoapSerializationEnvelope soapEnvelope = null;
	private HttpTransportSE httpSOAPTransport = null;
	
	public SOAPManager(Context context) {
		soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		httpSOAPTransport = new HttpTransportSE(SERVICE_URL);
		PrefrencesManager pm = PrefrencesManager.getInstance(context);
		final String url = pm.getStringFromPreferences("wsdl_url");
		if(url != null) {
			SERVICE_URL = url;
		}
	}
	
	public static String getServiceURL() {
		return MAIN_SERVICE_URL;
	}
	
	/** 
	 * Pobiera liste wszystkich kierunkow na UZ
	 * @param specializationList 
	 * @return 
	 * @throws XmlPullParserException 
	 * @throws IOException 
	 */
	public String[] downloadSpecializationList(final ArrayList<Kierunek> specializationList) throws IOException, XmlPullParserException {
		/** Nazwa funkcji do wywołania */
		final String METHOD_NAME = "pobierzListeKierunkow";
		final String SOAP_ACTION = SERVICE_NAMESPACE + "#" + METHOD_NAME;

		soapRequest = new SoapObject(SERVICE_NAMESPACE, METHOD_NAME);
		soapEnvelope.setOutputSoapObject(soapRequest);

		callSOAPMethod(SOAP_ACTION);


		SoapObject soapResponse = (SoapObject) soapEnvelope.getResponse();
		// Ilość wszystkich kierunków na UZ
		final Integer responseObjectsCount = soapResponse.getPropertyCount();

		String[] specializationNames = new String[responseObjectsCount];

		for(int index = 0; index < responseObjectsCount; index++) {
			final Object property = soapResponse.getProperty(index);
			if(property instanceof SoapObject) {

				final Kierunek kierunek = new Kierunek((SoapObject)property);

				specializationList.add(kierunek);

				specializationNames[index] = kierunek.getNazwa();
			}
		}

		Arrays.sort(specializationNames);
		Collections.sort(specializationList, Kierunek.getComparator());

		return specializationNames;
	}
	

	
	public String[] downloadDepartmentsList(final ArrayList<Wydzial> departmentsList) throws IOException, XmlPullParserException {
		/** Nazwa funkcji do wywołania */
		final String METHOD_NAME = "pobierzWydzialy";
		final String SOAP_ACTION = SERVICE_NAMESPACE + "#" + METHOD_NAME;

		soapRequest = new SoapObject(SERVICE_NAMESPACE, METHOD_NAME);
		soapEnvelope.setOutputSoapObject(soapRequest);

		callSOAPMethod(SOAP_ACTION);


		SoapObject soapResponse = (SoapObject) soapEnvelope.getResponse();
		// Ilość wszystkich kierunków na UZ
		final Integer responseObjectsCount = soapResponse.getPropertyCount();

		final String[] facultiesNames = new String[responseObjectsCount];

		for(int index = 0; index < responseObjectsCount; index++) {
			final Object property = soapResponse.getProperty(index);
			if(property instanceof SoapObject) {
				final Wydzial wydzial = new Wydzial((SoapObject)property);

				facultiesNames[index] = wydzial.getNazwa();

				departmentsList.add(wydzial);
			}
		}

		Arrays.sort(facultiesNames);
		Collections.sort(departmentsList, Wydzial.getComparator());
		
		return facultiesNames;
	}
	
	/**
	 * 
	 * @param context
	 * @throws IOException
	 * @throws XmlPullParserException
	 */
	public void downloadTeachersIDFromPers(final Context context) throws IOException, XmlPullParserException {
		/** Nazwa funkcji do wywołania */
		final String METHOD_NAME = "pobierzNauczycieliZPers";
		final String SOAP_ACTION = SERVICE_NAMESPACE + "#" + METHOD_NAME;

		soapRequest = new SoapObject(SERVICE_NAMESPACE, METHOD_NAME);
		soapEnvelope.setOutputSoapObject(soapRequest);


		callSOAPMethod(SOAP_ACTION);

		SoapObject soapResponse = (SoapObject) soapEnvelope.getResponse();
		// Ilość wszystkich kierunków na UZ
		final Integer responseObjectsCount = soapResponse.getPropertyCount();

		ArrayList<Nauczyciel> teachersList = new ArrayList<Nauczyciel>(responseObjectsCount);

		for(int index = 0; index < responseObjectsCount; index++) {
			final Object property = soapResponse.getProperty(index);
			if(property instanceof SoapObject) {
				final Nauczyciel nauczyciel = new Nauczyciel((SoapObject)property);

				teachersList.add(nauczyciel);
			}
		}

		PersDataSource ds = new PersDataSource(context, true);
		ds.writeNauczycielePers(teachersList);
	}
	
	/**
	 * Pobiera wykładowców pracujących w danym wydziale
	 * @param departmentId - id wydziału
	 * @return 
	 * @throws XmlPullParserException 
	 * @throws IOException 
	 */
	public ArrayList<String> downloadTeachersForDepartment(final Integer departmentId, final ArrayList<Nauczyciel> teachersList) throws IOException, XmlPullParserException {
		/** Nazwa funkcji do wywołania */
		final String METHOD_NAME = "pobierzListeNauczycieliDlaWydzialu";
		final String SOAP_ACTION = SERVICE_NAMESPACE + "#" + METHOD_NAME;

		soapRequest = new SoapObject(SERVICE_NAMESPACE, METHOD_NAME);
		soapRequest.addProperty("id", departmentId);
		soapEnvelope.setOutputSoapObject(soapRequest);

		callSOAPMethod(SOAP_ACTION);


		SoapObject soapResponse = (SoapObject) soapEnvelope.getResponse();
		// Ilość wszystkich kierunków na UZ
		final Integer responseObjectsCount = soapResponse.getPropertyCount();

		ArrayList<String> teachersNames = new ArrayList<String>();

		for(int index = 0; index < responseObjectsCount; index++) {
			final Object property = soapResponse.getProperty(index);
			if(property instanceof SoapObject) {
				final Nauczyciel nauczyciel = new Nauczyciel((SoapObject)property);

				teachersNames.add(nauczyciel.getNazwa());

				teachersList.add(nauczyciel);
			}
		}
		
		return teachersNames;
	}
	/**
	 * Pobiera informacje o wykładowcy z systemu PERS
	 * @param teacherID - id wykładowcy w systemie PERS
	 * @return 
	 * @throws XmlPullParserException 
	 * @throws IOException 
	 */
	public NauczycielInfo downloadTeacherInfoFromPers(final Integer teacherID) throws IOException, XmlPullParserException {
		/** Nazwa funkcji do wywołania */
		final String METHOD_NAME = "pobierzNauczycielPersInfo";
		final String SOAP_ACTION = SERVICE_NAMESPACE + "#" + METHOD_NAME;

		soapRequest = new SoapObject(SERVICE_NAMESPACE, METHOD_NAME);
		soapRequest.addProperty("id", teacherID);
		soapEnvelope.setOutputSoapObject(soapRequest);

		callSOAPMethod(SOAP_ACTION);

		SoapObject soapResponse = (SoapObject) soapEnvelope.getResponse();
		// Ilość odebranych obiektów
		final Integer responseObjectsCount = soapResponse.getPropertyCount();

		NauczycielInfo nauczycielInfo = null;

		for(int index = 0; index < responseObjectsCount; index++) {
			final Object property = soapResponse.getProperty(index);
			if(property instanceof SoapObject) {
				nauczycielInfo = new NauczycielInfo((SoapObject)property);
			}
		}
		
		return nauczycielInfo;
	}
	
	public void downloadNews(final ArrayList<News> newsList) throws IOException, XmlPullParserException {
		/** Nazwa funkcji do wywołania */
		final String METHOD_NAME = "pobierzNewsy";
		final String SOAP_ACTION = SERVICE_NAMESPACE + "#" + METHOD_NAME;

		soapRequest = new SoapObject(SERVICE_NAMESPACE, METHOD_NAME);
		soapEnvelope.setOutputSoapObject(soapRequest);

		callSOAPMethod(SOAP_ACTION);

		SoapObject soapResponse = (SoapObject) soapEnvelope.getResponse();
		// Ilość wszystkich newsów
		final Integer responseObjectsCount = soapResponse.getPropertyCount();

		for(int index = 0; index < responseObjectsCount; index++) {
			final Object property = soapResponse.getProperty(index);
			if(property instanceof SoapObject) {
				final News news = new News((SoapObject)property);

				newsList.add(news);
			}
		}
	}
	
	
 
	/** 
	 * Pobiera liste grup na wybranym kierunku
	 * @return 
	 * @throws XmlPullParserException 
	 * @throws IOException 
	 */
	public String[] downloadGroupsList(final Integer specializationId, ArrayList<Grupa> groupsList) throws IOException, XmlPullParserException {
		/** Nazwa funkcji do wywołania */
		final String METHOD_NAME = "pobierzListeGrupDlaKierunku";
		final String SOAP_ACTION = SERVICE_NAMESPACE + "#" + METHOD_NAME;

		soapRequest = new SoapObject(SERVICE_NAMESPACE, METHOD_NAME);
		soapRequest.addProperty("idKierunku", specializationId);
		soapEnvelope.setOutputSoapObject(soapRequest);

		callSOAPMethod(SOAP_ACTION);

		SoapObject soapResponse = (SoapObject) soapEnvelope.getResponse();
		// Ilość wszystkich grup na UZ
		final Integer responseObjectsCount = soapResponse.getPropertyCount();

		String[] groupsNames = new String[responseObjectsCount];

		for(int index = 0; index < responseObjectsCount; index++) {
			final Object property = soapResponse.getProperty(index);
			if(property instanceof SoapObject) {

				final Grupa grupa = new Grupa((SoapObject)property);

				groupsList.add(grupa);

				groupsNames[index] = grupa.getNazwa();
			}
		}

		Arrays.sort(groupsNames);
		Collections.sort(groupsList, Grupa.getComparator());

		return groupsNames;
	}
	
	/** 
	 * Wywołuje wybrane metody webservice'u
	 * @throws XmlPullParserException 
	 * @throws IOException 
	 */
	private void callSOAPMethod(final String SOAP_ACTION) throws IOException, XmlPullParserException {
			httpSOAPTransport.call(SOAP_ACTION, soapEnvelope);
	}
	/** Pobiera plan wybranej grupy 
	 * @return 
	 * @throws XmlPullParserException 
	 * @throws IOException */
	public Plan downloadGroupTimeTable(final Grupa group) throws IOException, XmlPullParserException {
		/** Nazwa funkcji do wywołania */
		final String METHOD_NAME = "pobierzPlanGrupy";
		final String SOAP_ACTION = SERVICE_NAMESPACE + "#" + METHOD_NAME;

		soapRequest = new SoapObject(SERVICE_NAMESPACE, METHOD_NAME);
		soapRequest.addProperty("idGrupy", group.getIdGrupy());
		soapEnvelope.setOutputSoapObject(soapRequest);

		Plan plan = new Plan();
		plan.setGroup(group);

		callSOAPMethod(SOAP_ACTION);

		SoapObject soapResponse = (SoapObject) soapEnvelope.getResponse();
		SoapObject listaPrzedmiotow = (SoapObject) soapResponse.getProperty(0);
		// Ilość wszystkich przedmiotow w planie tygodniowym grupy
		final Integer responseObjectsCount = listaPrzedmiotow.getPropertyCount();



		for(int index = 0; index < responseObjectsCount; index++) {
			final Object property = listaPrzedmiotow.getProperty(index);
			if(property instanceof SoapObject) {
				final SoapObject soapObj = (SoapObject)property;

				final Przedmiot przedmiot = new Przedmiot(soapObj);
				plan.addPrzedmiot(przedmiot);

				// Obsługa typu Sala
				{
					final SoapObject classSoapObj = (SoapObject) soapObj.getProperty("sala");
					final Integer idSali = Integer.parseInt(classSoapObj.getProperty("idSali").toString());
					final String symbolBudynku = classSoapObj.getProperty("symbolBudynku").toString();
					final String nazwa = classSoapObj.getProperty("nazwa").toString();
					final Sala sala = new Sala(idSali, symbolBudynku, nazwa);
					plan.addSala(sala);
				}
				// Obsługa typu Nauczyciel
				{
					final SoapObject teacherSoapObj = (SoapObject) soapObj.getProperty("nauczyciel");
					final Integer idNauczyciela = Integer.parseInt(teacherSoapObj.getProperty("idNauczyciela").toString());
					final String nazwa = teacherSoapObj.getProperty("nazwa").toString();
					final Nauczyciel nauczyciel = new Nauczyciel(idNauczyciela, nazwa);
					plan.addNauczyciel(nauczyciel);
				}

			}
		}
		return plan;
	}

	public Plan downloadTeacherTimeTable(Nauczyciel selectedTeacher) throws IOException, XmlPullParserException {
		/** Nazwa funkcji do wywołania */
		final String METHOD_NAME = "pobierzPlanNauczyciela";
		final String SOAP_ACTION = SERVICE_NAMESPACE + "#" + METHOD_NAME;

		soapRequest = new SoapObject(SERVICE_NAMESPACE, METHOD_NAME);
		soapRequest.addProperty("idGrupy", selectedTeacher.getIdNauczyciela());
		soapEnvelope.setOutputSoapObject(soapRequest);

		Plan plan = new Plan();
		plan.setTeacher(selectedTeacher);

		callSOAPMethod(SOAP_ACTION);

		SoapObject soapResponse = (SoapObject) soapEnvelope.getResponse();
		SoapObject listaPrzedmiotow = (SoapObject) soapResponse.getProperty(0);
		// Ilość wszystkich przedmiotow w planie tygodniowym grupy
		final Integer responseObjectsCount = listaPrzedmiotow.getPropertyCount();

		for(int index = 0; index < responseObjectsCount; index++) {
			final Object property = listaPrzedmiotow.getProperty(index);
			if(property instanceof SoapObject) {
				final SoapObject soapObj = (SoapObject)property;

				final Przedmiot przedmiot = new Przedmiot(soapObj);
				plan.addPrzedmiot(przedmiot);

				// Obsługa typu Sala
				{
					final SoapObject classSoapObj = (SoapObject) soapObj.getProperty("sala");
					final Integer idSali = Integer.parseInt(classSoapObj.getProperty("idSali").toString());
					final String symbolBudynku = classSoapObj.getProperty("symbolBudynku").toString();
					final String nazwa = classSoapObj.getProperty("nazwa").toString();
					final Sala sala = new Sala(idSali, symbolBudynku, nazwa);
					plan.addSala(sala);
				}
				// Obsługa typu Nauczyciel
				{
					final SoapObject teacherSoapObj = (SoapObject) soapObj.getProperty("nauczyciel");
					final Integer idNauczyciela = Integer.parseInt(teacherSoapObj.getProperty("idNauczyciela").toString());
					final String nazwa = teacherSoapObj.getProperty("nazwa").toString();
					final Nauczyciel nauczyciel = new Nauczyciel(idNauczyciela, nazwa);
					plan.addNauczyciel(nauczyciel);
				}

			}
		}
		
		return plan;
	}

}
